﻿using System.Collections;
using System.Collections.Generic;
using UnityEngine;
/// <summary>
/// 法阵线类    缓存池功能代办
/// </summary>
public class MagicLine : OBJBase, IResource
{
    #region 地图格子的交叉向量
    Vector3 headToLeftDown;
    Vector3 tailToLeftDown;

    Vector3 headToRightDown;
    Vector3 tailToRightDown;

    Vector3 leftUpToTaill;
    Vector3 rightUpToTaill;
    Vector3 leftDownToTaill;
    Vector3 rightDownToTaill;
    float lineAreaMaxX;  //线条区域最大X
    float lineAreaMaxZ;
    float lineAreaMinX;
    float lineAreaMinZ;
    #endregion
    GameObject line;
    LineRenderer lineR;
    Vector3 lineHead; //起点
    Vector3 lineTail; //终点
    Vector3 lineVec;
    E_MagicLine_Type lineType;//线条的类型
    BoxCollider boxCollider;
    //public Material[] materials;
    Vector3[] linePro = new Vector3[3];//线段起 终 向量
    int[] lineSeiralNameber = new int[2];
    List<float[]> areaGridList = new List<float[]>();
    List<int[]> passGrid = new List<int[]>();
    public GameObject Line { get => line; set => line = value; }
    public MagicLine() { }
    #region 初始化
    public MagicLine(bool isShow, Vector3 head, Vector3 tail, string name, E_MagicLine_Type lineType, Transform parent)
    {

        ResourceObject("ObjectRes/Line");
        Line.transform.SetParent(DrawMagic.GetInstance().MagicCircles.transform);
        Line.gameObject.name = name;
        Line.transform.eulerAngles = new Vector3(90, 0, 0);
        Line.layer = LayerMask.NameToLayer("MagicGraph");
        lineR = Line.GetComponent<LineRenderer>();
        IsShow(isShow);
        SetLinePosition(head, tail);
        lineHead = head;
        lineTail = tail;
        lineVec = lineHead - lineTail;
        linePro[0] = lineHead;
        linePro[1] = lineTail;
        linePro[2] = lineVec;
        switch (lineType)
        {
            case E_MagicLine_Type.ModelLine:
                lineR.material = GameManager.GetInstance().material[5];
                EventService.AddEventListener<E_MagicModeLine_State>(E_Event_Type.ModelLineState, ModelLineStateChange);
                break;
            case E_MagicLine_Type.MagicLine:
                lineR.material = GameManager.GetInstance().material[2];
                boxCollider = Line.transform.GetComponentInChildren<BoxCollider>();
                if (head.x >= tail.x)
                {
                    if (head.z >= tail.z)
                    {
                        boxCollider.transform.position = new Vector3((head.x - tail.x) / 2 + tail.x, 0.3f, (head.z - tail.z) / 2 + tail.z);
                    }
                    else
                    {
                        boxCollider.transform.position = new Vector3((head.x - tail.x) / 2 + tail.x, 0.3f, (tail.z - head.z) / 2 + tail.z);
                    }
                }
                else
                {
                    if (head.z > tail.z)
                    {
                        boxCollider.transform.position = new Vector3((tail.x - head.x) / 2 + tail.x, 0.3f, (head.z - tail.z) / 2 + tail.z);
                    }
                    else
                    {
                        boxCollider.transform.position = new Vector3((tail.x - head.x) / 2 + tail.x, 0.3f, (tail.z - head.z) / 2 + tail.z);
                    }
                }

                break;
        }
    }
    /// <summary>
    /// 样条线状态改变
    /// </summary>
    /// <param name="material"></param>
    /// <param name="state"></param>
    void ModelLineStateChange(E_MagicModeLine_State state)
    {
        switch (state)
        {
            case E_MagicModeLine_State.CorrectLine:
                lineR.material = GameManager.GetInstance().material[5];
                break;
            case E_MagicModeLine_State.WrongLine:
                lineR.material = GameManager.GetInstance().material[3];
                break;
        }
    }
    /// <summary>
    /// 加载资源
    /// </summary>
    /// <param name="url">资源路径</param>
    /// <returns></returns>
    public override GameObject ResourceObject(string url)
    {
        Line = GameObject.Instantiate<GameObject>(Resources.Load<GameObject>(url) as GameObject);
        return Line;
    }
    /// <summary>
    /// 线条对象设置
    /// </summary>
    /// <param name="isShow">是否显示</param>
    /// <param name="head">头部位置</param>
    /// <param name="trail">尾部位置</param>
    public void SetLine(bool isShow, Vector3 head, Vector3 trail)
    {
        IsShow(isShow);
        SetLinePosition(head, trail);
    }
    /// <summary>
    /// 线条显示
    /// </summary>
    /// <param name="isShow"></param>
    void IsShow(bool isShow)
    {
        if (Line.gameObject != null)
        {
            Line.gameObject.SetActive(isShow);
        }
        else
        {
            Debug.LogError($"线条{Line}对象为空");
        }
    }
    /// <summary>
    /// 设置LineRe
    /// </summary>
    /// <param name="startPos"></param>
    /// <param name="endPos"></param>
    void SetLinePosition(Vector3 startPos, Vector3 endPos)
    {
        lineR.SetPosition(0, startPos);
        lineR.SetPosition(1, endPos);
    }
    #endregion
    #region 线条覆盖的区域判定
    /// <summary>
    /// 线段的覆盖区域，是个矩形，判断线段进过了区域的哪些方块，
    /// </summary>
    /// <param name="lineSerialNamber"></param>
    /// <param name="lineHeadVec"></param>
    /// <param name="lineTailVec"></param>
    void LineArea(int lineSerialNamber, Vector3 lineHeadVec, Vector3 lineTailVec)
    {
        //判断x的范围
        if (lineHeadVec.x == lineTailVec.x)
        {
            lineAreaMaxX = lineHeadVec.x;
            lineAreaMinX = lineHeadVec.x;
        }
        else
        {
            if (lineHeadVec.x > lineTailVec.x)
            {

                lineAreaMaxX = lineHeadVec.x;
                lineAreaMinX = lineTailVec.x;
            }
            else
            {
                lineAreaMaxX = lineTailVec.x;
                lineAreaMinX = lineHeadVec.x;
            }
        }
        if (lineHeadVec.z == lineTailVec.z)
        {
            lineAreaMaxZ = lineHeadVec.z;
            lineAreaMinZ = lineHeadVec.z;
        }
        else
        {
            if (lineHeadVec.z > lineTailVec.z)
            {

                lineAreaMaxZ = lineHeadVec.z;
                lineAreaMinZ = lineTailVec.z;
            }
            else
            {
                lineAreaMaxZ = lineTailVec.z;
                lineAreaMinZ = lineHeadVec.z;
            }
        }
        //将区域点添加进管理列表
        for (float i = lineAreaMinZ; i < lineAreaMaxZ + 1; i++)
        {
            for (float j = lineAreaMinX; j < lineAreaMaxX + 1; j++)
            {
                float[] passGrid = { i, j };
                areaGridList.Add(passGrid);
            }
        }
    }

    bool IsLinesIntersect2(Vector3[] line, Vector3[] foldPoint)
    {

        headToLeftDown = line[0] - foldPoint[2];
        tailToLeftDown = line[1] - foldPoint[2];

        headToRightDown = line[0] - foldPoint[3];
        tailToRightDown = line[1] - foldPoint[3];

        leftUpToTaill = foldPoint[0] - line[1];
        rightUpToTaill = foldPoint[1] - line[1];
        leftDownToTaill = foldPoint[2] - line[1];
        rightDownToTaill = foldPoint[3] - line[1];
        int crossNumber0 = 0;
        int crossNumber1 = 0;
        //是否是线段两端
        if (line[0] == foldPoint[4] || line[1] == foldPoint[4])
        {
            return true;
        }
        if ((Vector3.Cross(foldPoint[5], headToRightDown).y > 0 && Vector3.Cross(foldPoint[5], tailToRightDown).y < 0) ||
            (Vector3.Cross(foldPoint[5], headToRightDown).y < 0 && Vector3.Cross(foldPoint[5], tailToRightDown).y > 0))
        {
            crossNumber0++;
        }
        if ((Vector3.Cross(line[2], leftUpToTaill).y > 0 && Vector3.Cross(line[2], rightDownToTaill).y < 0) ||
            (Vector3.Cross(line[2], leftUpToTaill).y < 0 && Vector3.Cross(line[2], rightDownToTaill).y > 0)
        )
        {
            crossNumber0++;
        }

        if ((Vector3.Cross(foldPoint[6], headToLeftDown).y > 0 && Vector3.Cross(foldPoint[6], tailToLeftDown).y < 0) ||
            (Vector3.Cross(foldPoint[6], headToLeftDown).y < 0 && Vector3.Cross(foldPoint[6], tailToLeftDown).y > 0))
        {
            crossNumber1++;
        }
        if ((Vector3.Cross(line[2], rightUpToTaill).y > 0 && Vector3.Cross(line[2], leftDownToTaill).y < 0) ||
             (Vector3.Cross(line[2], rightUpToTaill).y < 0 && Vector3.Cross(line[2], leftDownToTaill).y > 0)
         )
        {
            crossNumber1++;
        }
        if (crossNumber0 != 0)
        {
            if (crossNumber0 % 2 == 0)
            {
                crossNumber0 = -1;
            }
        }
        if (crossNumber1 != 0)
        {
            if (crossNumber1 % 2 == 0)
            {
                crossNumber1 = -1;
            }
        }
        if (crossNumber0 == -1 || crossNumber1 == -1)
        {
            return true;
        }
        else
        {
            return false;
        }
    }
    /// <summary>
    /// 确定线段经过的路径方块
    /// </summary>
    public void ComfirmPassGrid(int magicGraphNumber, int lineNumber)
    {
        lineSeiralNameber[0] = magicGraphNumber;
        lineSeiralNameber[1] = lineNumber;
        LineArea(0, lineHead, lineTail);
        for (int i = 0; i < areaGridList.Count; i++)
        {
            if (IsLinesIntersect2(linePro, MapContorller.GetInstance().ArrayGrid[(int)areaGridList[i][0], (int)areaGridList[i][1]].AgAndFork))
            {
                int[] grid = new int[2];
                grid[0] = (int)areaGridList[i][0];
                grid[1] = (int)areaGridList[i][1];
                passGrid.Add(grid);
                //MapContorller.GetInstance().ArrayGrid[(int)areaGridList[i][0], (int)areaGridList[i][1]].ChangeMaterial(GameManager.GetInstance().material[4]);
                MapContorller.GetInstance().ArrayGrid[(int)areaGridList[i][0], (int)areaGridList[i][1]].E_Grid_Type = E_MapGrid_Type.Type_obstacle;
                MapContorller.GetInstance().ArrayGrid[(int)areaGridList[i][0], (int)areaGridList[i][1]].AddGridLineList(lineSeiralNameber);
            }
        }
    }
    #endregion
    #region 回收方法
    public void Hide()
    {

        IsShow(false);
        for (int i = 0; i < passGrid.Count; i++)
        {
            MapContorller.GetInstance().ArrayGrid[passGrid[i][0], passGrid[i][1]].RemoveLins(lineSeiralNameber);
        }
    }
    public void Recycle()
    {
        EventService.RemoveEventListener<E_MagicModeLine_State>(E_Event_Type.ModelLineState, ModelLineStateChange);
        GameObject.Destroy(Line);
    }
    #endregion
}

public enum E_MagicLine_Type
{
    ModelLine,
    MagicLine,
}
public enum E_MagicModeLine_State
{
    CorrectLine,
    WrongLine,
}